%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%  Copyright by Wenliang Du.                                       %%
%%  This work is licensed under the Creative Commons                %%
%%  Attribution-NonCommercial-ShareAlike 4.0 International License. %%
%%  To view a copy of this license, visit                           %%
%%  http://creativecommons.org/licenses/by-nc-sa/4.0/.              %%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\newcommand{\commonfolder}{../../common-files}

\input{\commonfolder/header}
\input{\commonfolder/copyright}


\lhead{\bfseries SEED Labs -- Mitnick 攻击实验室}
\newcommand{\mitnickFigs}{./Figs}

\newcommand{\rsh}{\texttt{rsh}\xspace}

\begin{document}



\begin{center}
{\LARGE Mitnick 攻击实验室}
\end{center}

\seedlabcopyright{2020}


% *******************************************
% SECTION
% ******************************************* 
\section{概述}

凯文·米特尼克（Kevin Mitnick）可能是美国最著名的黑客之一。他曾在FBI的通缉犯名单上。在逃亡期间，他对黑客攻击蜂窝电话网络产生了兴趣，并需要一些能够帮助他做到这一点的专用软件。这将他引向了筱村毅（Tsutomu Shimomura），一位在圣地亚哥超级计算中心工作的研究人员，也是蜂窝电话网络安全领域的领先研究者之一，掌握了米特尼克想要的代码。

在1994年，米特尼克成功发起了对筱村电脑的攻击，利用了TCP协议的漏洞以及筱村的两台电脑之间的信任关系。此次攻击引发了两人之间的戏剧性较量，最终导致了米特尼克的逮捕。这场较量后来被改编成了书籍和好莱坞电影。该攻击现被称为米特尼克攻击，这是一种特殊类型的TCP会话劫持。

本实验的目标是重现经典的米特尼克攻击，以便学生能够获得此次攻击的第一手经验。我们将模拟当初筱村电脑上的设置，然后发起米特尼克攻击，以在筱村的两台电脑之间创建伪造的TCP会话。如果攻击成功，我们应该能够在筱村的电脑上运行任何命令。此实验涵盖以下主题：

\begin{itemize}[noitemsep]
\item TCP会话劫持攻击
\item TCP三路握手协议
\item 米特尼克攻击
\item 远程 shell \rsh
\item 数据包嗅探和伪造
\end{itemize}


\paragraph{阅读材料和视频}
详细的TCP会话劫持内容可以在以下资料中找到：

\begin{itemize}
\item SEED书的第16章，\seedbook
\item SEED讲座的第6节，\seedisvideo
\end{itemize}

\paragraph{实验环境。} \seedenvironmentC



% *******************************************
% SECTION
% ******************************************* 
\section{米特尼克攻击如何工作}

米特尼克攻击是TCP会话劫持攻击的一种特殊情况。与其劫持受害者A和B之间的现有TCP连接，米特尼克攻击首先代表他们创建A和B之间的TCP连接，然后自然地劫持该连接。

在实际的米特尼克攻击中，主机A称为X-Terminal，这是一个目标。米特尼克想要登录到X-Terminal并在其上运行命令。主机B是一个受信任的服务器，它被允许无需密码登录X-Terminal。为了登录X-Terminal，米特尼克必须伪装成受信任的服务器，这样他就不需要提供任何密码。图~\ref{tcp:mitnick}描绘了该攻击的高层次动作。此攻击有四个主要步骤。

\begin{figure}[htb]
\centering
\includegraphics[width=0.8\textwidth]{\mitnickFigs/mitnick_attack.pdf}
\caption{米特尼克攻击的示意图}
\label{tcp:mitnick}
\end{figure}

\paragraph{步骤 1: 序列号预测。} 在攻击之前，米特尼克需要了解X-Terminal上的初始序列号（ISN）的模式（在那个时代，ISN并不随机）。米特尼克向X-Terminal发送SYN请求，并收到SYN+ACK响应，然后他发送RESET数据包到X-Terminal，以清除X-Terminal队列中的半开连接（以防止队列被填满）。在重复此操作20次后，他发现两个连续的TCP ISN之间存在模式。这使米特尼克能够预测ISN，这是攻击所必需的。

\paragraph{步骤 2: 对受信任服务器的SYN泛滥攻击。} 为了从受信任服务器向X-Terminal发送连接请求，米特尼克需要从受信任服务器向X-Terminal发送SYN数据包。X-Terminal会回复一个SYN+ACK数据包，该数据包会发送到受信任服务器。由于受信任服务器并未实际发起请求，因此它会向X-Terminal发送RESET数据包，请求X-Terminal停止三路握手。此行为对米特尼克攻击造成了麻烦。

为了解决这个问题，米特尼克必须使受信任的服务器保持静默。因此，在伪造之前，米特尼克对服务器发起了SYN泛滥攻击。那时，操作系统对SYN泛滥攻击非常脆弱。攻击实际上可以让受信任计算机关闭，完全使其静默。

\paragraph{步骤 3: 伪造TCP连接。} 米特尼克想要使用\rsh（远程shell）在X-Terminal上运行后门命令；一旦后门被设置，他就可以登录到X-Terminal。为了在X-Terminal上运行远程shell，米特尼克需要通过身份验证，即他需要在X-Terminal上拥有有效账户并知道其密码。显然，他没有这些。

筱村常常需要从受信任的服务器登录到X-Terminal。为了避免每次都输入密码，他在X-Terminal上的\texttt{.rhosts}文件中添加了一些信息，以便当他从受信任的服务器登录到X-Terminal时，不会要求密码。这在当时是一种相当常见的做法。有了这个设置，筱村可以使用\rsh从受信任的服务器运行命令，或者使用\texttt{rlogin}登录到X-Terminal，而无需输入任何密码。米特尼克想要利用这种信任关系。

他需要在受信任的服务器和X-Terminal之间创建TCP连接，然后在该连接中运行\rsh。 他首先向X-Terminal发送一个SYN请求，使用受信任服务器的IP作为源IP地址。X-Terminal随后向服务器发送SYN+ACK响应。由于服务器已关闭，因此它不会发送RESET来关闭连接。

为了完成三路握手协议，米特尼克需要伪造一个ACK数据包，该数据包必须确认X-Terminal的SYN+ACK数据包中的序列号。不幸的是，SYN+ACK响应只发送给受信任服务器，而不发送给米特尼克，因此他无法看到序列号。然而，由于之前的调查，米特尼克能够预测这个数字，因此他能够成功伪造发往X-Terminal的ACK响应，以完成TCP的三路握手。

\paragraph{步骤 4: 运行远程shell。} 
通过建立的受信任服务器与X-Terminal之间的TCP连接，米特尼克可以向X-Terminal发送远程shell请求，请求其执行命令。使用此命令，米特尼克希望在X-Terminal上创建一个后门，以便他能随时在X-Terminal上获得shell，而无需重复攻击。

他所需做的就是在X-Terminal的\texttt{.rhosts}文件中添加\texttt{"+ +"}。他可以通过在X-Terminal上使用\rsh执行以下命令来实现这一点：
{\tt "echo + + > .rhosts"}. 由于\rsh和\texttt{rlogin}程序使用\texttt{.rhosts}文件进行身份验证，添加此内容后，X-Terminal将信任来自任何人的每个\rsh和\texttt{rlogin}请求。

% *******************************************
% SECTION
% ******************************************* 
\section{使用容器设置实验环境}



% -------------------------------------------
% SUBSECTION
% ------------------------------------------- 
\subsection{容器设置}

在本实验中，我们需要三台机器， 一台用于X-Terminal，一台用于受信任服务器，另一台用于攻击者。
在实际的米特尼克攻击中，攻击者机器是远程机器。
为了简化，我们在同一网络上放置了这三台机器。 学生可以使用三台虚拟机进行本实验，但使用容器会更加方便。实验环境如图~\ref{mitnick:fig:labsetup}所示。

\begin{figure}[htb]
\begin{center}
\includegraphics[width=0.8\textwidth]{\commonfolder/Figs/Mitnick_onelan.pdf}
\end{center}
\caption{实验环境设置}
\label{mitnick:fig:labsetup}
\end{figure}
 

%\begin{lstlisting}[backgroundcolor=]
%            +------------+      +--------------+  +----------------+  
%            |     VM     |      |   Container  |  |    Container   |  
%            | (attacker) |      | (X-Terminal) |  |(Trusted Server)|  
%            |  10.9.0.1  |      |   10.9.0.5   |  |    10.9.0.6    |  
%            +----+-------+      +-------+------+  +--------+-------+  
%                 | br-<id>             | eth0          | eth0   
%                 |                     |               |        
%           ------+---------------------+---------------+--------------
%           Network  10.9.0.0/24
%
%\end{lstlisting}



% -------------------------------------------
% SUBSECTION
% -------------------------------------------
\subsection{容器设置和命令}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\input{\commonfolder/container/setup}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%



% -------------------------------------------
% SUBSECTION
% -------------------------------------------
\subsection{关于攻击者容器}

在本实验中，我们可以使用虚拟机或攻击者容器作为攻击者机器。如果你查看Docker Compose文件，你会发现攻击者容器的配置与其他容器不同。以下是这些区别：

\begin{itemize}
\item \textit{共享文件夹。} 当我们使用攻击者容器发起攻击时，我们需要将攻击代码放入攻击者容器内。

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\input{\commonfolder/container/volumes}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\item \textit{主机模式。}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\input{\commonfolder/container/host_mode}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\item \textit{特权模式。}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\input{\commonfolder/container/privileged_mode}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\end{itemize}


% -------------------------------------------
% SUBSECTION
% ------------------------------------------- 
\subsection{安装 \rsh 程序（不需要执行任何操作）}

远程 shell \rsh 是一个命令行程序，可以远程执行 shell 命令。虽然我们将在此任务中使用 \rsh，但我们应该知道\rsh和\texttt{rlogin}程序并不安全，而且它们不再使用。它们已被更安全的程序所取代，如\texttt{ssh}。
这就是为什么在现代Linux操作系统中，\rsh命令实际上是一个指向\texttt{ssh}程序的符号链接。

\begin{lstlisting}
$ ls -al /etc/alternatives | grep rsh
lrwxrwxrwx   1 root root    12 Jul 25  2017 rsh -> /usr/bin/ssh
\end{lstlisting}

为了重现米特尼克攻击，我们需要安装不安全版本的\rsh程序。显然，旧版本的\rsh已经不再工作，但一个开源项目重新实现了远程 shell 客户端和服务器。它被称为\texttt{rsh-redone}。我们可以使用以下命令安装\rsh服务器和客户端。 \textbf{注意：} \rsh程序已经安装在X-Terminal和Trusted Server容器中（请参见容器镜像文件夹内的\texttt{Dockerfile}）。

\begin{lstlisting}
$ sudo apt-get install rsh-redone-client
$ sudo apt-get install rsh-redone-server
\end{lstlisting}




% -------------------------------------------
% SUBSECTION
% ------------------------------------------- 
\subsection{配置}
\label{subsec:configuration}

\rsh服务器程序使用两个文件进行身份验证， \texttt{.rhosts} 和 \texttt{/etc/hosts.equiv}。每次服务器接收到远程命令请求时，它都会检查\texttt{/etc/hosts.equiv}。如果请求来自文件中存储的主机名，服务器将接受该请求而不要求输入密码。
如果\texttt{/etc/hosts.equiv}不存在或没有该主机名，\rsh 将检查用户主目录中的 \texttt{.rhosts} 文件。

筱村常常需要从受信任的服务器在X-Terminal上运行远程命令。为了避免输入密码，他在X-Terminal上创建了\texttt{.rhosts}文件，并将受信任服务器的IP地址放入该文件中。请注意，\texttt{.rhosts}文件必须位于用户主目录的顶级，并且只能由所有者/用户写入。

请使用以下命令在X-Terminal上设置\texttt{.rhosts}文件。需要注意的是，当我们进入容器时，我们将处于root账户中。在本实验中，我们需要切换到名称为“seed”的普通用户帐户，这个账户已经在容器中创建：

\begin{lstlisting}
# su seed          (*@\reflectbox{\ding{217}}@*) 切换到seed帐户
$ cd               (*@\reflectbox{\ding{217}}@*) 进入seed的主目录
$ touch .rhosts    (*@\reflectbox{\ding{217}}@*) 创建空文件 
$ echo [服务器的IP地址] > .rhosts
$ chmod 644 .rhosts
\end{lstlisting}

要验证配置，请尝试在受信任服务器上运行以下命令。
\begin{lstlisting}
# su seed          (*@\reflectbox{\ding{217}}@*) 切换到seed帐户
$ rsh [X-Terminal的IP] date
\end{lstlisting}

如果命令打印当前日期和时间，则配置正常工作。如果您看到“身份验证失败”，则设置中的某些内容可能不正确。常见错误之一是在\texttt{.rhosts}文件上的权限：您应该确保该文件仅对所有者可写。

\paragraph{允许所有} 要允许用户从所有IP地址在X-Terminal上执行命令，我们只需在\texttt{.rhosts}文件中放入两个加号（\texttt{"+ +"}）。这非常危险，任何人都不应该这样做。但如果您是一个攻击者，这是一个设置后门的方便方式。正如我们之前提到的，这正是米特尼克攻击中使用的方式。

% *******************************************
% SECTION
% ******************************************* 
\section{任务1：模拟SYN泛滥}

米特尼克攻击发生时，操作系统易受SYN泛滥攻击的影响，这可能使目标机器静默甚至关闭。然而，对于现代操作系统，SYN泛滥已经不能再造成如此损害。我们将模拟这种效果。

我们可以手动停止受信任服务器容器，但这并不够。当X-Terminal接收到来自受信任服务器的SYN数据包时，它将以SYN+ACK数据包作出响应。在发送此数据包之前，它需要知道受信任服务器的MAC地址。会先检查ARP缓存。如果没有受信任服务器的条目，X-Terminal将发送ARP请求数据包以请求MAC地址。由于受信任服务器已被静默，所以没有人会回应该ARP请求，因此X-Terminal无法发送响应。因此，TCP连接不会建立。

在实际攻击中，受信任服务器的MAC地址实际上在X-Terminal的ARP缓存中。即使没有，在使受信任服务器静默之前，我们可以简单地伪造一个ICMP回显请求从受信任服务器发送到X-Terminal，这将触发X-Terminal回复受信任服务器，从而得到受信任服务器的MAC地址，并将其保存到缓存中。

为了简化任务，在停止受信任服务器之前，我们将从X-Terminal对其进行ping一次，然后使用\texttt{arp}命令检查并确保MAC地址在缓存中。需要注意的是，如果操作系统无法使用缓存的MAC地址到达目标，缓存条目可能会被操作系统删除。为了简化攻击，您可以在X-Terminal上运行以下命令以永久添加一个条目到ARP缓存（需要在root帐户中运行）：

\begin{lstlisting}
# arp -s [服务器的IP] [服务器的MAC]
\end{lstlisting}

% *******************************************
% SECTION
% ******************************************* 
\section{任务2：伪造TCP连接和 \rsh 会话}
\label{sec:task2}

现在我们“让”受信任服务器“关闭”，我们可以冒充受信任服务器，并尝试与X-Terminal发起\rsh会话。由于\rsh在TCP之上运行，我们首先需要在受信任服务器和X-Terminal之间建立TCP连接，然后在此TCP连接中运行\rsh。

米特尼克攻击中的一个困难是预测TCP序列号。当时TCP序列号是不随机的，因此这成为可能。然而，现代操作系统现在会随机化其TCP序列号（作为对TCP会话劫持攻击的对策），因此预测这些数字变得不可行。为了模拟原始米特尼克攻击的情况，我们允许学生嗅探数据包，以便他们能够获取序列号，而不是进行猜测。

\paragraph{限制} 为了尽可能接近原始米特尼克攻击，即使学生能够从X-Terminal嗅探TCP数据包，他们也不能使用捕获数据包中的所有字段，因为在实际攻击中，米特尼克无法嗅探数据包。当学生编写他们的攻击程序时，他们只能使用捕获数据包中的以下字段。如果使用其他字段，将会受到惩罚。

\begin{itemize}
\item \textbf{TCP序列号字段}（这不包括确认字段）。

\item \textbf{TCP标志字段}。这使我们能够知道捕获的TCP数据包类型。在实际的米特尼克攻击中，米特尼克确切知道X-Terminal发送了哪种类型的数据包，因为它们是TCP三次握手协议的一部分。我们允许学生在任务简化中使用此字段。

\item \textbf{所有长度字段}，包括IP头长度，IP总长度和TCP头长度。这些信息对于攻击并不是必需的。在实际的米特尼克攻击中，米特尼克确切知道它们的值。我们允许学生使用这些字段以简化任务。
\end{itemize}

\paragraph{\rsh 的行为} 
为了在受信任服务器和X-Terminal之间创建伪造的\rsh会话，我们需要了解\rsh的行为。让我们从受信任服务器到X-Terminal开始一个\rsh会话，然后使用Wireshark捕获它们之间的数据包（注意：我们将在攻击者虚拟机上运行Wireshark，请确保选择正确的网络接口，与\texttt{10.9.0.0/24}网络对应）。我们使用以下命令通过\rsh在主机A上运行主机B的\texttt{date}命令。

\begin{lstlisting}
// 在受信任的服务器上
$ rsh 10.9.0.5 date
\end{lstlisting}

以下是此\rsh会话的数据包跟踪。这里\texttt{10.9.0.6}是受信任服务器的IP地址，\texttt{10.9.0.5}是X-Terminal的IP地址。如果数据包不携带TCP数据，则长度信息（即\texttt{Len=0}）被省略。

\begin{lstlisting}[caption={\rsh会话的数据包跟踪},
                  label={listing:rsh}]
# 第一个连接
   源 IP      目标 IP   TCP 头部
1  10.9.0.6  10.9.0.5  1023 -> 514 [SYN] Seq=778933536 
2  10.9.0.5  10.9.0.6  514 -> 1023 [SYN,ACK] Seq=10879102 Ack=778933537 
3  10.9.0.6  10.9.0.5  1023 -> 514 [ACK] Seq=778933537 Ack=10879103 
4  10.9.0.6  10.9.0.5  1023 -> 514 [ACK] Seq=778933537 Ack=10879103 Len=20
                       RSH会话建立
                       数据：1022\x00seed\x00seed\x00date\x00
5  10.9.0.5  10.9.0.6  514 -> 1023 [ACK] Seq=10879103 Ack=778933557

# 第二个连接
6  10.9.0.5  10.9.0.6  1023 -> 1022 [SYN] Seq=3920611526 
7  10.9.0.6  10.9.0.5  1022 -> 1023 [SYN,ACK] Seq=3958269143 Ack=3920611527 
8  10.9.0.5  10.9.0.6  1023 -> 1022 [ACK] Seq=3920611527 Ack=3958269144 

# 返回第一个连接
9  10.9.0.5  10.9.0.6  514 -> 1023 [ACK] Seq=10879103 Ack=778933557 Len=1
                       数据：\x00
10 10.9.0.6  10.9.0.5  1023 -> 514 [ACK] Seq=778933557 Ack=10879104 
11 10.9.0.5  10.9.0.6  514 -> 1023 [ACK] Seq=10879104 Ack=778933557 Len=29
                       数据：Sun Feb 16 13:41:17 EST 2020
\end{lstlisting}

我们可以观察到，\rsh会话包含两个TCP连接。第一个连接由主机A（客户端）发起。主机B上的\texttt{rshd}进程在514端口侦听连接请求。数据包1到3用于三路握手协议。连接建立后，客户端将\rsh数据（包括用户ID和命令）发送到主机B（数据包4）。\texttt{rshd}进程将验证用户，如果用户通过身份验证，\texttt{rshd}将与客户端发起一个单独的TCP连接。

第二个连接用于发送错误消息。在上面的跟踪中，由于没有错误，因此未使用此连接，但必须成功建立该连接，否则\texttt{rshd}将不会继续。数据包6到7是第二个连接的三路握手协议。

在第二个连接建立后，主机B将发送一个零字节到客户端（使用第一个连接），主机A将确认该数据包。在这之后，主机B上的\texttt{rshd}将运行客户端发送的命令，命令的输出将通过第一个连接发送回客户端。学生可以使用Wireshark捕获\rsh会话并研究其行为，然后再发起米特尼克攻击。我们将攻击任务分为两个子任务，每个子任务专注于一个连接。

% -------------------------------------------
% SUBSECTION
% ------------------------------------------- 
\subsection{任务2.1: 伪造第一个TCP连接}
\label{sec:first-conn}

第一个TCP连接由攻击者通过伪造的SYN数据包发起。如图~\ref{fig:first-conn}所示，当X-Terminal接收到SYN数据包后，它会向受信任服务器发送SYN+ACK数据包。由于服务器已被关闭，因此它不会重置连接。攻击者位于同一网络，可以嗅探数据包以获取序列号。

\begin{figure}[htb]
\centering
\includegraphics[width=0.6\textwidth]{\mitnickFigs/mitnick-diagram-1.pdf}
\caption{第一个连接}
\label{fig:first-conn}
\end{figure}

\paragraph{步骤1: 伪造一个SYN数据包。} 学生应该编写程序来伪造一个从受信任服务器到X-Terminal的SYN数据包（见数据包1，列出~\ref{listing:rsh}）。TCP标头中有六个标准代码位，可以在标志字段中设置。以下代码示例显示了如何设置标志字段以及如何检查某些位是否在标志字段中设置。

\begin{lstlisting}
# 'U': URG位
# 'A': ACK位
# 'P': PSH位
# 'R': RST位
# 'S': SYN位
# 'F': FIN位

tcp = TCP()

# 设置SYN和ACK位
tcp.flags = "SA"

# 检查SYN和ACK是否是唯一设置的位
if tcp.flags == "SA": 

# 检查SYN和ACK位是否被设置
if 'S' in tcp.flags and 'A' in tcp.flags: 
\end{lstlisting}

需要注意的是，SYN数据包的源端口必须来自端口\texttt{1023}。如果使用不同的端口，\rsh在连接建立后会重置该连接。如果此步骤成功，通过Wireshark，我们应该能够看到来自X-Terminal的SYN+ACK数据包（见数据包2，列出~\ref{listing:rsh}）。

\paragraph{步骤2: 回复SYN+ACK数据包。} 在X-Terminal发送SYN+ACK后，受信任服务器需要发送ACK数据包以完成三路握手协议。数据包中的确认号应为\texttt{S+1}，其中\texttt{S}是SYN+ACK数据包中的序列号。见数据包3，列出~\ref{listing:rsh}。

在实际的米特尼克攻击中，攻击者无法看到SYN+ACK数据包，因为它是发送给受信任服务器的，而不是给攻击者。因此，米特尼克不得不猜测序列号的值。在本实验中，我们允许学生通过嗅探数据包获取序列号。

学生需要编写一个使用\texttt{Scapy}的嗅探与伪造程序，并在攻击者机器上运行。以下是一个可能有用的嗅探与伪造程序的骨架。请确保遵循本节开头描述的限制，否则将会受到惩罚。

\begin{lstlisting}
#!/usr/bin/python3
from scapy.all import *

x_ip      = "10.9.0.5"  # X-Terminal
x_port    = 514         # X-Terminal使用的端口号

srv_ip    = "10.9.0.6"  # 受信任服务器
srv_port  = 1023        # 受信任服务器使用的端口号

# 在伪造的SYN中加1序列号
seq_num     = 0x1000 + 1


def spoof(pkt):
  global seq_num   # 我们将在函数中更新此全局变量

  old_ip  = pkt[IP]
  old_tcp = pkt[TCP]

  # 打印调试信息
  tcp_len = old_ip.len - old_ip.ihl*4 - old_tcp.dataofs*4  # TCP数据长度
  print("{}:{} -> {}:{}  Flags={} Len={}".format(old_ip.src, old_tcp.sport,
                         old_ip.dst, old_tcp.dport, old_tcp.flags, tcp_len))

  # 构建响应的IP头
  ip = IP(src=srv_ip, dst=x_ip)

  # 检查是否为SYN+ACK数据包；
  # 如果是，则伪造一个ACK数据包

  # ... 在此添加代码 ...

myFilter = 'tcp'   # 需要使过滤器更加具体
sniff(iface='br-****', filter=myFilter, prn=spoof)
                  (*@\reflectbox{\ding{218}} \textbf{您需要在这里设置正确的值。}@*)   
\end{lstlisting}

\paragraph{步骤3: 伪造\rsh数据包} 一旦连接建立，攻击者需要向X-Terminal发送\rsh数据。 \rsh数据的结构如下所示。

\begin{lstlisting}
[端口号]\x00[客户端用户ID]\x00[服务器用户ID]\x00[您的命令]\x00
\end{lstlisting}

数据包含四个部分：端口号、客户端用户ID、服务器用户ID和命令。端口号将用于第二个连接（见任务2.2）。在我们的容器中，客户端和服务器的用户ID都是\texttt{seed}。这四个字段由一个字节0分隔。请注意，在\rsh数据的末尾也有一个字节0。以下是一个示例。在此示例中，我们告诉X-Terminal，我们将监听端口9090以进行第二个连接，并且我们想要执行的命令是\texttt{"touch /tmp/xyz"}。

\begin{lstlisting}
data = '9090\x00seed\x00seed\x00touch /tmp/xyz\x00'
send(IP()/TCP()/data, verbose=0)
\end{lstlisting}

学生应修改步骤2中编写的嗅探与伪造程序，以便向X-Terminal发送\rsh数据包（见数据包4，列出~\ref{listing:rsh}）。如果此步骤成功，通过Wireshark我们可以看到X-Terminal会向受信任服务器的端口\texttt{9090}发起TCP连接，这是在我们的\rsh数据中指定的端口号。

在您的报告中，请描述在X-Terminal上是否执行了\texttt{touch}命令。还请附上您的Wireshark快照。

% -------------------------------------------
% SUBSECTION
% ------------------------------------------- 
\subsection{任务2.2: 伪造第二个TCP连接}
\label{sec:second-conn}

\begin{figure}[htb]
\centering
\includegraphics[width=0.6\textwidth]{\mitnickFigs/mitnick-diagram-2.pdf}
\caption{第二个连接}
\label{fig:second-conn}
\end{figure}

在第一个连接建立后，X-Terminal将发起第二个连接。此连接用于\texttt{rshd}发送错误消息。在我们的攻击中，我们不会使用此连接，但如果未建立该连接，\texttt{rshd}将不会执行我们的命令。因此，我们需要使用伪造技术帮助X-Terminal和受信任服务器完成建立该连接。见图~\ref{fig:second-conn}。

学生需要编写另一个嗅探与伪造程序，嗅探发送到受信任服务器端口9090的TCP流量（假设在任务2.1中使用了\texttt{9090}）。当它看到SYN数据包时，它应该用SYN+ACK数据包作出响应。见数据包7，列出~\ref{listing:rsh}中的描述。

如果两个连接都成功建立，\texttt{rshd}将执行\rsh数据包中包含的命令。请检查\texttt{/tmp}文件夹，查看\texttt{/tmp/xyz}是否被创建，时间戳是否与当前时间匹配。请在您的报告中附上证据。

% *******************************************
% SECTION
% ******************************************* 
\section{任务3: 设置后门}

在任务2中，我们只是在攻击中运行了\texttt{touch}命令，以证明我们可以成功地在X-Terminal上运行命令。如果我们想要在后续运行更多命令，我们每次都要进行相同的攻击，这非常不方便。

米特尼克确实计划再次回到X-Terminal。在初次攻击后，他在X-Terminal中植入了一个后门。这个后门使他每次想要的时候都能正常登录到X-Terminal，而无需输入任何密码。为了实现这个目标，正如我们在 \ref{subsec:configuration} 节中讨论的那样，我们所需要做的就是在 \texttt{.rhosts} 文件中添加字符串 \texttt{"+ +"}（以单行形式）。我们可以在我们的 \rsh 数据中包含以下命令。

\begin{lstlisting}
echo + + > .rhosts
\end{lstlisting}

学生应将任务2中的\texttt{touch}命令替换为上面的\texttt{echo}命令，然后重复攻击。如果攻击成功，攻击者应能够使用以下命令远程登录到X-Terminal，而无需输入密码：

\begin{lstlisting}
$ rsh [X-Terminal的IP]
\end{lstlisting}

\rsh程序可能未在攻击者容器上安装，但可以使用以下命令轻松安装：

\begin{lstlisting}
# apt-get update && apt-get -y install rsh-redone-client 
\end{lstlisting}

% *******************************************
% SECTION
% ******************************************* 
\section{作业提交}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\input{\commonfolder/submission}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%



\end{document}